package com.apes.scm.stock.transfer.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.util.Tools;
import com.apes.scm.account.account.service.ProductAccountService;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.stock.transfer.model.ConsumableUse;
import com.apes.scm.stock.transfer.model.ConsumableUseItem;
import com.apes.scm.stock.transfer.model.Pick;
import com.apes.scm.stock.transfer.model.PickItem;
import com.apes.scm.stock.transfer.repository.ConsumableUseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;


/**
 * 功能：耗材领用服务
 *
 * @author zhuyh
 * @time 11:46
 * @date 2019/11/21
 */
@Service("consumableuseService")
public class ConsumableUseService extends DomainService {

    @Autowired
    private ConsumableUseRepository consumableUseRepository;


    @Autowired
    private ProductAccountService productAccountService;


    /**
     * 创建耗材领用
     ****
     * @param request
     * @return
     */
    public ConsumableUse create(SimpleRequest request) {
        ConsumableUse consumableUse = request.getO(ConsumableUse.class);
        if ("HC000".equals(consumableUse.getScene().getId())) this.judgeHCProduct(consumableUse); // 判断是否是耗材商品
        ConsumableUse finalConsumableUse = saveConsumableUse(consumableUse);
        finalConsumableUse.getConsumableUseItems()
                .stream().forEach((consumableUseItem -> productAvailableService(finalConsumableUse, consumableUseItem, -1.00, "耗材领用单新增")));
        return finalConsumableUse;
    }


    private ConsumableUse saveConsumableUse(ConsumableUse consumableUse) {
        consumableUse.setCompany(consumableUse.getLocation().getCompany());
        if (Tools.isNull(consumableUse.getState())) {
            consumableUse.setState("sent");
        }
        consumableUse.setDateCreate(new Date());
        return consumableUseRepository.saveAndFlush(consumableUse);
    }


    /**
     * 可用数
     */
    private void productAvailableService(ConsumableUse consumableUse, ConsumableUseItem consumableUseItem, Double unit, String remarks) {
        productAccountService.setProductAvailable(consumableUseItem.getProduct(),
                consumableUse.getLocation(), consumableUseItem.getUom(), unit * consumableUseItem.getUseQty(),
                consumableUse.getInnerBusinessType(), consumableUse.getId(), consumableUseItem.getId(),
                remarks, consumableUse.getCompany());
    }



    /**
     * 功能：创建交货单
     * 根据仓库汇总
     *
     * @param request
     */
    private Pick createPickOrder(SimpleRequest request) {

        Set<PickItem> pickItems = new HashSet<>();

        ConsumableUse order = request.getO(ConsumableUse.class);
        //  根据明细上面的仓库进行汇总数据

        order.getConsumableUseItems().stream().forEach(
                saleItem -> {
                    PickItem pickItem = new PickItem();
                    pickItem.setProduct(saleItem.getProduct());
                    pickItem.setUom(saleItem.getUom());
                    pickItem.setOrderedQty(saleItem.getUseQty());
                    pickItem.setProductUomQty(saleItem.getUseQty());
                    pickItem.setOriginLine(saleItem.getId());
                    pickItems.add(pickItem);
                }
        );

        Pick pick = new Pick();

        if ("HC000".equals(order.getScene().getId())) {
            pick.setAuto(true);
            if (Objects.nonNull( order.getClerk())) pick.setNote("交货单自动发货--"+ order.getClerk().getName());
        }

        pick.setMoveType(order.getMoveType());

        pick.setPartner(order.getCompany());
        pick.setLocation(order.getLocation());
        pick.setCompany(order.getLocation().getCompany());     // 公司为库区的公司

        pick.setOrigin(order.getId());
        pick.setOriginBusinessType(order.getInnerBusinessType());
        pick.setOperation("deliver");               // 交货类型：交货
        pick.setScene(order.getScene());            // 注入场景
        pick.setPickItems(pickItems);


        // 创建交货单
//        EventUtil.sendSynEvent(this,"event:stock.pick.save", pick);

        return pick;
    }


    /**
     * 功能: 修改
     *
     * @param request
     * @return
     */
    public ConsumableUse update(SimpleRequest request) {
        ConsumableUse consumableUse = request.getO(ConsumableUse.class);
        ConsumableUse oldConsumableUse = consumableUseRepository.findOne(consumableUse.getId());
        // 可用数先增加后减少
        oldConsumableUse.getConsumableUseItems().stream().forEach((consumableUseItem -> productAvailableService(oldConsumableUse, consumableUseItem, 1.00, "耗材领用单修改")));
        ConsumableUse newConsumableUse = consumableUseRepository.saveAndFlush(consumableUse);
        consumableUse.getConsumableUseItems().stream().forEach((consumableUseItem -> productAvailableService(newConsumableUse, consumableUseItem, -1.00, "耗材领用单修改")));

        return newConsumableUse;
    }


    /**
     * 功能：删除订单
     */
    public String delete(SimpleRequest request) {

        String id = request.get("id");
        ConsumableUse consumableUse = consumableUseRepository.findOne(id);
        if (consumableUse == null) throw new RuntimeException("订单：" + request.get("id") + " 在系统中不存在。");
        if (consumableUse.getState().equals("confirmed"))
            throw new RuntimeException("订单：" + request.get("id") + " 在系统中已审批。");

        // 加可用数
        consumableUse.getConsumableUseItems().stream().forEach((saleOrderItem -> productAvailableService(consumableUse, saleOrderItem, 1.00, "耗材领用单订单删除")));

        consumableUse.setState("delete");

        consumableUseRepository.saveAndFlush(consumableUse);
        return "删除成功！";
    }


    /**
     * 功能：审批订单
     *
     * @param request
     * @return
     */
    public ConsumableUse approve(SimpleRequest request) {
        String id = request.get("id");
        ConsumableUse consumableUse = consumableUseRepository.findOne(id);
        if (consumableUse == null) throw new RuntimeException("订单：" + id + " 在系统中不存在。");
        if (consumableUse.getVersion() != (int) request.get("version")) throw new RuntimeException("记录已更新或已删除，请重新提交！");
        if (consumableUse.getState().equals("confirmed")) throw new RuntimeException("订单：" + id + " 在系统中已审批。");
        consumableUse.setState("confirmed");
        consumableUse.setDateApprove(new Date());

        consumableUse = consumableUseRepository.saveAndFlush(consumableUse);
        // 创建交货单 -- 挪到场景流中
//        request.setData(consumableUse);
//        createPickOrder(request);

        return consumableUse;
    }

    // 交货完成
    @Listener(topic = "event:stock.pick.delivery")
    public void pickDelivery(SimpleRequest simpleRequest) {
        JSONObject getJO = simpleRequest.getJO();
        if (!getJO.getString("originBusinessType").equals(ConsumableUse.class.getSimpleName())) return;
        ConsumableUse consumableUse = consumableUseRepository.findOne(getJO.getString("origin"));
        if (consumableUse == null) return;
        consumableUse.setState("done");
        consumableUse.setDateDone(new Date());
        consumableUseRepository.saveAndFlush(consumableUse);
    }


    /**
     * 判断是否是耗材商品
     * @param consumableUse
     */
    private void judgeHCProduct(ConsumableUse consumableUse) {
        List<String> products = new ArrayList<>();
        consumableUse.getConsumableUseItems().forEach(consumableUseItem -> products.add(consumableUseItem.getProduct().getId()));
        List<Product> productList = SpringManager.getBean(ProductRepository.class).queryConsumableProduct(products, 0);
        if (productList.size() > 0) {
            AtomicReference<String> product = new AtomicReference<>();
            productList.forEach(singleProduct -> product.getAndSet(singleProduct.getId() + ";"));
            throw new RuntimeException("以下不属于免费耗材商品: " + product);
        }
    }

}
